package router

import (
	"60321/pkg/controller"
	"60321/pkg/global"
	"60321/pkg/middleware"
	"60321/pkg/models"
	"fmt"
	"github.com/gin-contrib/cors"
	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v5"
	"net/http"
	"time"
)

func SetUpRouter() *gin.Engine {
	r := gin.Default()
	r.Use(cors.New(cors.Config{
		// 允许所有来源
		AllowAllOrigins: true,
		// 允许的 HTTP 方法
		AllowMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"},
		// 允许的请求头
		AllowHeaders: []string{"Origin", "Content-Type", "Content-Length", "Authorization", "RefreshToken"},
		// 允许的响应头
		ExposeHeaders: []string{"Content-Length"},
		// 允许携带凭证
		AllowCredentials: true,
		// 预检请求缓存时间
		MaxAge: 12 * time.Hour,
	}))
	r.GET("/hello", func(c *gin.Context) {
		c.JSON(200, gin.H{"hello": "world"}) // 用于测试连接
	})
	auth := r.Group("/auth")
	{
		auth.POST("/api/register", controller.Register) // 注册一个用户
		auth.POST("/api/login", controller.Login)       // 登入
	}
	city := r.Group("/city")
	{
		city.GET("/api/city/:id", controller.GetNearlyCity)                                // 返回某个城市的信息和它的附近城市信息
		city.GET("/api/city", controller.GetCity)                                          // 返回所有城市的信息
		city.GET("/api/city/taxi/:id", controller.GetCityTaxi)                             // 返回这个城市的出租车信息
		city.GET("/api/city/urbanCharacteristics/:id", controller.GetUrbanCharacteristics) // 返回城市的特色
	}
	ticket := r.Group("/ticket")
	ticket.Use(Authorization())
	{
		ticket.POST("/api/ticket", controller.BuyTicket)          // 买票 核心
		ticket.GET("/api/ticket", controller.GetTickets)          // 获取所有的票信息
		ticket.GET("/api/ticket/:id", controller.GetTicket)       // 获得单个票
		ticket.POST("/api/queryCity", controller.GetTicketByCity) // 查询这个票经过的城市
	}
	admin := r.Group("/admin") // 管理数据库 对数据库增删查改 添加测试数据
	admin.Use(Authorization(), middleware.AdminMiddleware())
	{
		admin.POST("/api/city/city", controller.AddCitiesInDB)             //  添加一个城市
		admin.POST("/api/taxi/taxi", controller.AddTaxisInDB)              // 添加一个出租车信息
		admin.POST("/api/ticket/ticket", controller.AddTicketsInDB)        // 添加一个票信息
		admin.POST("/api/city/adjacent", controller.AddCityAdjacent)       // 添加一个相邻城市信息
		admin.POST("/api/ticket/city", controller.AddAdjacentCityInTicket) // 添加一个票相邻城市
		admin.GET("/api/taxi/taxi", controller.GetTaxis)                   // 获取出租车的信息
	}
	return r
}
func Authorization() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 从请求头中获取 Token
		tokenString := c.GetHeader("Authorization")
		if tokenString == "" {
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "未提供 Token"})
			return
		}

		// 解析 Token
		token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
			// 验证 Token 的签名方法
			if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
				return nil, fmt.Errorf("无效的签名方法")
			}
			return []byte("default-secret-key"), nil
		})

		if err != nil {
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "无效的 Token"})
			return
		}

		if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
			// 从 Token 中提取用户信息
			phone := claims["phone"].(string)

			// 查询用户
			var user models.UserModel
			if err := global.Db.Where("phone = ?", phone).First(&user).Error; err != nil {
				c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "用户不存在"})
				return
			}

			// 将用户角色设置到 Context 中
			c.Set("role", user.Role)
			c.Set("user", user)
		} else {
			c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "无效的 Token"})
			return
		}

		c.Next()
	}
}
